import { useGlobSetting } from './../hook/setting/index';
import axios from 'axios';
import type {
  AxiosRequestConfig,
  AxiosResponse,
  AxiosError,
  InternalAxiosRequestConfig,
} from 'axios';
import router from '@/router';
import { message } from 'ant-design-vue';
import { requestAgainSend } from './axionsRetry';
import { getAuthCache } from './auth';
const globalConfig = useGlobSetting();

const instance = axios.create({
  baseURL: globalConfig.apiUrl,
  timeout: 10000,
});

// 请求拦截
instance.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const key = getAuthCache('TOKEN_KEY');
    if (key) {
      config.headers!.Authorization = key;
    }
    return config;
  },
  (err: AxiosError<any, any>) => {
    return Promise.reject(err);
  },
);

// 响应拦截
instance.interceptors.response.use(
  (response: AxiosResponse) => {
    const { status, data } = response;
    const { url } = response.config;
    if (status == 200) return data;
    else if (status == 401 || status == 403) {
      router.replace({
        path: '/login',
        query: { redirect: encodeURIComponent(JSON.stringify(url)) },
      });
    } else {
      message.error(data.message || '网络连接异常');
      return Promise.reject(data.message || new Error('网络连接异常'));
    }
  },
  async (error: AxiosError<any, any>) => {
    requestAgainSend(error, instance);

    const { data } = error.response as AxiosRequestConfig;
    if (error.response) {
      if (
        error.response.status === 401 ||
        error.response.status === 403 ||
        data?.message?.indexOf('请重新登录') != -1
      ) {
        localStorage.clear();
        router.replace({
          path: '/login',
          query: { redirect: encodeURIComponent(JSON.stringify(window.location.pathname)) },
        });
      }
    }

    return Promise.reject(error);
  },
);
class request {
  static get<T>(url: string, paramObj: {} = {}, option?: any): Promise<T> {
    return instance.get(url, { params: paramObj, ...option });
  }
  static post<T>(url: string, params: {} = {}, option?: any): Promise<T> {
    return instance.post(url, params, option);
  }
  static put<T>(url: string, params: {} = {}, option?: any): Promise<T> {
    return instance.put(url, params, option);
  }
  static delete<T>(url: string, params: string): Promise<T> {
    return instance.delete(`${url}/${params}`);
  }
}

export default request;
